package parsers;

import helpers.CacheHelper;
import helpers.ParsingHelper;

import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import datamodel.Entry;
import datamodel.PossibleMatch;
import datamodel.TVShow;

public class TVParser implements ParserCommand {
	Vector<TVShow> tvShows;

	public TVParser( Vector<TVShow> tvShows ) {
		this.tvShows = tvShows;
	}

	public boolean isParseable( Entry entry ) {
		return entry.isTVShow();
	}

	public void executeSearchParsing( Entry entry ) throws Exception {
		// See if this show has already been found
		if ( entry.getShow().isProcessed() == false ) {
			StringBuffer buffer = CacheHelper.getCachedFile( "http://www.tv.com/search.php?type=11&stype=all&qs="
					+ entry.getTitle() );

			Pattern hitPattern = Pattern.compile( "Show: <a(.*) href=\"(.*)summary.html(.*)\">(.*)</a>" );

			PossibleMatch possibleMatch = new PossibleMatch();

			Matcher m = hitPattern.matcher( buffer );

			while ( m.find() ) {
				possibleMatch.addMatch( m.group( 4 ), m.group( 2 ) );
			}

			entry.setPossibleMatch( possibleMatch );

			// Mark this show as having been found
			entry.getShow().setProcessed( true );

			// Set every episode except for the first one to processed,
			// so that the user isn't prompted for every single episode
			// when it is a single TV Show
			Vector<Entry> episodes = entry.getShow().getEpisodes();

			for ( int i = 1; i < episodes.size(); i++ ) {
				episodes.elementAt( i ).setProcessed( true );
			}
		}
	}

	public void executeFinalParsing( Entry entry ) throws Exception {
		Vector<Entry> episodes = entry.getShow().getEpisodes();

		String baseUrl = entry.getInetref();

		// Go through every episode assigned to this show
		for ( Entry episode : episodes ) {
			StringBuffer buffer = CacheHelper.getCachedFile( baseUrl + "episode_listings.html?season="
					+ episode.getSeason() + "&tag=nav_bar;1" );

			StringBuilder content = ParsingHelper.parseBetween( buffer, "<div id=\"episode-listing\"",
					"</div id=\"main-col\">" );

			Pattern hitPattern = Pattern
					.compile( "<td class=\"first(.*)\\n(\\s*)(\\d*)\\n(.*)\\n(.*)\\n(\\s*)<a href=\"(.*)\">(.*)</a>" );

			Matcher m = hitPattern.matcher( content );

			// Their episode numbers start from the beginning of the show
			// Figure out their offset
			int episodeNumber = 1;

			String episodeURL = null;

			while ( m.find() ) {
				if ( episode.getEpisode() == episodeNumber ) {
					episodeURL = m.group( 7 );
					break;
				}

				episodeNumber++;
			}

			if ( episodeURL == null ) {
				// We couldn't find the data we needed. So set the entry back to
				// unchanged
				System.out.println( "Could not find the episode data for " + entry.getShow().getShowName() + " season "
						+ episode.getSeason() + " episode " + episode.getEpisode() );
				episode.setChanged( false );

				continue;
			}

			StringBuffer episodeBuffer = CacheHelper.getCachedFile( episodeURL );

			String title = episode.getTitle() + "-"
					+ ParsingHelper.findGroup( "Episode: <span class=\"f-FF9\">(.*)</span><br />", episodeBuffer, 1 );

			String director = ParsingHelper.findGroup(
					"Director:\\n(\\s*)</td>\\n(\\s*)<td>\\n(\\s*)<a href=(.*)\">(.*)</a>", episodeBuffer, 5 );
			String plotOutline = ParsingHelper.findGroup( "<div id=\"main-col\">\\n\\n(\\s*)<div>\\n(\\s*)(.*)",
					episodeBuffer, 3 );

			// They don't have the ratings for these shows
			String rating = "TV";
			String year = ParsingHelper.findGroup( "First Aired: (.*), (\\d*) &nbsp;", episodeBuffer, 2 );
			String userRating = ParsingHelper.findGroup(
					"<span class=\"f-28 f-bold mt-10 mb-10 f-FF9 db lh-18\">(.*)</span>", episodeBuffer, 1 );

			// They don't have the length but most shows are 30 minutes
			String length = "30";

			episode.setTitle( title );
			episode.setDirector( director );
			episode.setPlot( plotOutline );
			episode.setRating( rating );
			episode.setYear( year );
			episode.setUserrating( userRating );
			episode.setLength( length );

			episode.setInetref( ParsingHelper.findGroup( "/show/(\\d*)", baseUrl, 1 ) );

			episode.setProcessed( true );
		}
	}
}
